package com.yuyou.fn.report.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.google.common.base.Function;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.CriteriaUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.CourseClass;
import com.yuyou.fn.educational.service.ICourseClassService;
import com.yuyou.fn.platform.permission.DataPermission;
import com.yuyou.fn.report.entity.ConsumeRecord;
import com.yuyou.fn.report.mapper.ConsumeRecordMapper;
import com.yuyou.fn.report.service.IConsumeRecordService;
import com.yuyou.fn.report.vo.*;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 *
 * ConsumeRecord 表数据服务层接口实现类
 *
 */
@Service
public class ConsumeRecordServiceImpl extends SuperServiceImpl<ConsumeRecordMapper, ConsumeRecord,String> implements IConsumeRecordService {

    private final static Logger log  = LoggerFactory.getLogger(ConsumeRecordServiceImpl.class);

    @Resource
    private ICourseClassService courseClassService;


    @Override
    public List<AggregationConsumeRecordVo> aggregateConsume(ConsumeRecordQueryVo consumeRecordQueryVo, Date start, Date end, DataPermission dataPermission) {

        if(start == null || end == null ){
            throw new BusException("Required query times");
        }


        Example<ConsumeRecord> example = ConsumeRecord.createExample();
        Example.Criteria criteria = example.createCriteria();

        CriteriaUtils.fillCondition(criteria, consumeRecordQueryVo );
        criteria.andGreaterThanOrEqualTo("createTime" ,start ).andLessThanOrEqualTo("createTime" , DateUtils.addDays(end , 1 ) );

        List<ConsumeRecord> consumeRecordList = findListByExample(example);
        List<AggregationConsumeRecordVo> aggregationConsumeRecords = aggregate(consumeRecordList,  start,  end);
        return aggregationConsumeRecords;
    }

    private List<AggregationConsumeRecordVo> aggregate(List<ConsumeRecord> consumeRecordList, Date start, Date end ) {
        List<Long> classIds  = BeanUtils.toList(consumeRecordList,"classId");
        List<CourseClass> courseClasses  = courseClassService.findByIds(Utils.unique(classIds));
        Map<Long,CourseClass> courseClassMaps = BeanUtils.toMap(courseClasses,"classId");
        Function<ConsumeRecord,String> groupByForConsumeRecord = (input)->input.getRegId() + "|" +input.getClassId() ;
        Map<String,List<ConsumeRecord>> groupOfConsumeRecord =  BeanUtils.toGroup(consumeRecordList , groupByForConsumeRecord );
        List<AggregationConsumeRecordVo> aggregationConsumeRecords = new ArrayList<>(consumeRecordList.size());
        for(Map.Entry<String,List<ConsumeRecord>> entry : groupOfConsumeRecord.entrySet() ){
            ConsumeRecord one = entry.getValue().get(0);
            AggregationConsumeRecordVo aggregationConsumeRecordVo = new AggregationConsumeRecordVo();
            BeanUtils.copyProperties(aggregationConsumeRecordVo,one);
            aggregationConsumeRecordVo.setGroupKey(entry.getKey());
            aggregationConsumeRecordVo.setConsumeAmountOfThis(BigDecimal.ZERO);
            aggregationConsumeRecordVo.setConsumeClassTimeOfThis(0);
            aggregationConsumeRecordVo.setRedAmountOfThis(BigDecimal.ZERO);
            aggregationConsumeRecordVo.setDifferenceAmountOfThis(BigDecimal.ZERO);
            aggregationConsumeRecordVo.setStartDate(start);
            aggregationConsumeRecordVo.setEndDate(end);

            for(ConsumeRecord consumeRecord : entry.getValue() ){
                if(consumeRecord.getType() == 0 ){
                    aggregationConsumeRecordVo.setConsumeAmountOfThis(aggregationConsumeRecordVo.getConsumeAmountOfThis().add(consumeRecord.getAmount()));
                    aggregationConsumeRecordVo.setConsumeClassTimeOfThis(aggregationConsumeRecordVo.getConsumeClassTimeOfThis() + 2 );
                }else if(consumeRecord.getType() == 1 ){
                    aggregationConsumeRecordVo.setRedAmountOfThis(aggregationConsumeRecordVo.getRedAmountOfThis().add(consumeRecord.getAmount()));
                }else if(consumeRecord.getType() == 2 ){
                    aggregationConsumeRecordVo.setDifferenceAmountOfThis(aggregationConsumeRecordVo.getDifferenceAmountOfThis().add(consumeRecord.getAmount()));
                }
            }

            CourseClass courseClass = courseClassMaps.get(one.getClassId());
            if(courseClass != null ){
                aggregationConsumeRecordVo.setClassNo(courseClass.getClassNo());
                aggregationConsumeRecordVo.setTeacherName(courseClass.getTeacherName());
                aggregationConsumeRecordVo.setClassName(courseClass.getClassName());
            }
            aggregationConsumeRecords.add(aggregationConsumeRecordVo);
        }
        return aggregationConsumeRecords ;
    }

    @Override
    public List<ConsumeCollectVo> findConsumeCollect(ConsumeCollectQueryVo consumeCollectQueryVo, DataPermission dataPermission) {
        return autoMapper.findConsumeCollect(consumeCollectQueryVo,dataPermission.getBusTeamIds());
    }



    @Override
    public List<BusTeamPeriodConsumeVo> findBusTeamPeriodConsumeVo(long periodId) {
        return autoMapper.findBusTeamPeriodConsume(periodId);
    }
}